import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:mall/constants.dart';
import 'package:mall/core/models/account.dart';
import 'package:mall/core/models/account_detail.dart';
import 'package:mall/core/models/ad.dart';
import 'package:mall/core/models/address.dart' as address;
import 'package:mall/core/models/bank.dart';
import 'package:mall/core/models/business_apply.dart';
import 'package:mall/core/models/business_condition.dart';
import 'package:mall/core/models/business_level.dart';
import 'package:mall/core/models/cart_add.dart';
import 'package:mall/core/models/cart_list.dart';
import 'package:mall/core/models/group_history_res.dart';
import 'package:mall/core/models/logistics.dart';
import 'package:mall/core/models/message.dart';
import 'package:mall/core/models/news_query.dart';
import 'package:mall/core/models/order_checkout.dart';
import 'package:mall/core/models/order_checkout_req.dart';
import 'package:mall/core/models/order_confirm.dart';
import 'package:mall/core/models/order_confirm_req.dart';
import 'package:mall/core/models/order_detail.dart';
import 'package:mall/core/models/order_list.dart';
import 'package:mall/core/models/point_exchange_account.dart';
import 'package:mall/core/models/point_exchange_history_res.dart';
import 'package:mall/core/models/product_detail.dart';
import 'package:mall/core/models/search.dart';
import 'package:mall/core/models/store_apply_query.dart';
import 'package:mall/core/models/store_categories.dart';
import 'package:mall/core/models/store_detail.dart';
import 'package:mall/core/models/store_index.dart';
import 'package:mall/core/models/store_pin_gou.dart';
import 'package:mall/core/models/store_product_query.dart';
import 'package:mall/core/models/store_search.dart';
import 'package:mall/core/models/store_total.dart';
import 'package:mall/core/models/team_and_port.dart';
import 'package:mall/core/models/user_invited.dart';
import 'package:mall/core/models/user_renew_list.dart';
import 'package:mall/core/models/user_total.dart';
import 'package:mall/core/models/withdraw.dart';
import 'package:mall/core/services/dio_interceptor.dart';
import 'package:mall/core/providers/app_model.dart';
import 'package:intl/intl.dart';
import 'package:mall/core/services/http.dart';

class Api {
  final AppModel appModel;
  final Dio _client;

  Api(this.appModel) : _client = Http() {
    debugPrint('$this init $_client');
    _client
      ..options.baseUrl = api_base_url
      ..interceptors.add(DioInterceptor(appModel));
  }

  /// 启动页广告
  Future<List<Ad>> adStart() async {
    var params = {
      'clientId': clientId,
      'linkType': 'START_AD',
      'storeId': appModel.bindingStoreId,
    };
    var response = await _client.post('/api/ad/start', data: params);
    return response.data.map<Ad>((value) => Ad.fromJson(value)).toList();
  }

  /// 商品详情
  Future<ProductDetail> productDetail(
    int areaId,
    int pid,
    int mid,
    int referStoreId,
    CancelToken cancelToken,
  ) async {
    var params = {
      'aid': areaId,
      'pid': pid,
      'mid': mid,
      'r': referStoreId,
    };
    var response = await _client.get(
      '/api/product/detail',
      queryParameters: params,
      cancelToken: cancelToken,
    );
    return ProductDetail.fromJson(response.data);
  }

  /// 加入购物车
  Future<CartAdd> cartAdd(
    int mid,
    int quantity,
    String referStoreId, {
    bool replace = false,
  }) async {
    var params = {
      "mia": "$mid",
      "quantity": "$quantity",
      "r": referStoreId,
      'replace': replace,
    };
    var response = await _client.post("/api/cart/add", queryParameters: params);
    return CartAdd.fromJson(response.data);
  }

  /// 检查能否下单
  Future orderCheck(Map<int, int> cartIdQuantity) async {
    var response = await _client.post(
      '/api/order/check',
      data: cartIdQuantity.map((key, value) => MapEntry('$key', value)),
    );
    return response.data;
  }

  /// 获取拼购订单确认界面的展示信息
  Future<OrderConfirm> orderConfirmEx(Map<int, int> cartIdQuantity, List<int> portIds) async {
    final req = OrderConfirmReq(cartIdQuantity: cartIdQuantity, userPortMappingIds: portIds);
    final response = await _client.post("/api/order/confirm/ex", data: req);
    return OrderConfirm.fromJson(response.data);
  }

  /// 行政区查询
  Future<Map<String, dynamic>> addressRegionQuery(String id) async {
    var params = {'p': id};
    var response = await _client.get('/api/address/region/query', queryParameters: params);
    return response.data;
  }

  /// 创建或更新用户配送地址
  Future addressUpdate(address.Address address) async {
    var response = await _client.post('/api/address/update', data: address);
    return response.data;
  }

  /// 地址删除
  Future addressDelete(int addressId) async {
    var response = await _client.get('/api/address/delete/$addressId');
    return response.data;
  }

  /// 地址验证码发送
  Future<String> addressSms(String phone) async {
    var response = await _client.get('/api/address/sms/$phone');
    return response.data;
  }

  /// 购物车列表
  Future<CartList> cartList(CancelToken cancelToken) async {
    var response = await _client.get('/api/cart/list', cancelToken: cancelToken);
    return CartList.fromJson(response.data);
  }

  /// 购物车数量变更
  Future cartChange(int cartId, int quantity) async {
    var params = {'shopCartId': cartId, 'quantity': quantity};
    var response = await _client.post('/api/cart/change', data: FormData.fromMap(params));
    return response.data;
  }

  /// 购物车记录删除
  Future cartRemove(int cartId) async {
    var params = {'shopCartId': cartId};
    var response = await _client.post('/api/cart/remove', data: FormData.fromMap(params));
    return response.data;
  }

  /// 提交订单，并支付
  Future<OrderCheckout> orderCheckoutNew(OrderCheckoutReq req) async {
    final response = await _client.post('/api/order/checkout', data: req);
    return OrderCheckout.fromJson(response.data);
  }

  /// 用户各类信息统计数量
  Future<UserTotal> userTotal(CancelToken cancelToken) async {
    var response = await _client.get('/api/user/total', cancelToken: cancelToken);
    var userTotal = UserTotal.fromJson(response.data);
    // 更新可切换店铺
    appModel.switchableStoreList = userTotal.storeOptions;
    // 更新可管理店铺
    appModel.manageableStoreList = {}
      ..addAll(userTotal.storeOptions)
      ..removeWhere((key, value) => userTotal.unmanagedStoreIds.contains(int.tryParse(key) ?? 0));
    return userTotal;
  }

  /// 订单列表
  /// status 订单状态：0全部，1待支付，2待发货，3待收货
  Future<OrderList> orderList(
    int storeId,
    int status,
    int page,
    CancelToken cancelToken,
  ) async {
    var params = {
      's': status,
      'p': page,
      'ps': 10,
    };
    var response = await _client.get(
      storeId == null ? '/api/order/list' : '/api/store/$storeId/order',
      queryParameters: params,
      cancelToken: cancelToken,
    );
    return OrderList.fromJson(response.data);
  }

  /// 订单详情
  Future<OrderDetail> orderDetail(int storeId, String code, CancelToken cancelToken) async {
    var response = await _client.get(
      storeId == null ? '/api/order/$code' : '/api/store/$storeId/order/$code',
      cancelToken: cancelToken,
    );
    return OrderDetail.fromJson(response.data);
  }

  /// 店铺详情
  Future<StoreDetail> storeDetail(int id, CancelToken cancelToken) async {
    var params = {
      'clientId': clientId,
      'storeId': id,
    };
    var response = await _client.post('/api/store/detail', data: params, cancelToken: cancelToken);
    return StoreDetail.fromJson(response.data);
  }

  /// 店铺详情
  Future<StoreDetail> storeDetailNew({int storeId}) async {
    final params = {
      "clientId": clientId,
      "storeId": storeId ?? appModel.bindingStoreId,
    };
    final response = await _client.post("/api/store/detail", data: params);
    return StoreDetail.fromJson(response.data);
  }

  /// 银行卡列表
  Future<List<Bank>> bankList() async {
    var response = await _client.get('/api/bank/list');
    return response.data.map<Bank>((value) => Bank.fromJson(value)).toList();
  }

  /// 银行卡删除
  Future bankDelete(int id) async {
    var response = await _client.get('/api/bank/delete/$id');
    return response.data;
  }

  /// 银行账户类型
  Future<Map<String, dynamic>> bankType() async {
    var response = await _client.get('/api/bank/accounttype');
    return response.data;
  }

  /// 银行账户更新
  Future bankUpdate(Bank bank) async {
    var response = await _client.post('/api/bank/update', data: bank);
    return response.data;
  }

  /// 店铺提现记录查询
  Future<List<Withdraw>> withdrawQuery(int storeId, int page) async {
    var params = {'sid': storeId, 'pi': page, 'ps': 10};
    var response = await _client.get('/api/withdraw/query', queryParameters: params);
    return response.data.map<Withdraw>((value) => Withdraw.fromJson(value)).toList();
  }

  /// 提现记录申请审核
  Future withdrawApply(int id) async {
    var response = await _client.get('/api/withdraw/apply/$id');
    return response.data;
  }

  /// 撤回已提交的提现申请
  Future withdrawCancel(int id) async {
    var response = await _client.get('/api/withdraw/cancel/$id');
    return response.data;
  }

  /// 撤回已提交的提现申请
  Future withdrawDelete(int id) async {
    var response = await _client.get('/api/withdraw/delete/$id');
    return response.data;
  }

  /// 获取店铺可提现账户名称和余额
  Future<Map<String, dynamic>> withdrawAccount() async {
    var response = await _client.get('/api/withdraw/account');
    return response.data;
  }

  /// 创建店铺提现记录
  Future withdrawCreate(Map<String, dynamic> params) async {
    var response = await _client.post('/api/withdraw/create', data: params);
    return response.data;
  }

  /// 账户列表查询接口
  Future<List<Account>> accountList(String category) async {
    var response = await _client.get('/api/useraccount/list/$category');
    return response.data.map<Account>((value) => Account.fromJson(value)).toList();
  }

  /// 获取用户信息接口
  Future<List<Message>> messageQuery(int page, CancelToken cancelToken) async {
    var params = {'pi': page, 'ps': 10};
    var response = await _client.get(
      '/api/usermessage/query',
      queryParameters: params,
      cancelToken: cancelToken,
    );
    return response.data.map<Message>((value) => Message.fromJson(value)).toList();
  }

  /// 用户信息已阅
  Future messageView(int id) async {
    var response = await _client.get('/api/usermessage/view/$id');
    return response.data;
  }

  /// 店铺商品查询接口
  Future<StoreProductQuery> storeProductQuery(
    int storeId,
    int categoryId,
    int storeAreaId,
    int page,
    CancelToken cancelToken,
  ) async {
    var params = {
      'categoryId': categoryId,
      'clientId': clientId,
      'pageIndex': page,
      'pageSize': 10,
      'queryKey': null,
      'storeAreaId': storeAreaId,
      'storeId': storeId,
    };
    var response = await _client.post(
      '/api/store/product/query',
      data: params,
      cancelToken: cancelToken,
    );
    return StoreProductQuery.fromJson(response.data);
  }

  /// 店铺商品查询接口
  Future<StoreProductQuery> storeProductQueryNew(
    int storeId,
    int categoryId,
    int areaId,
    String queryKey,
    int pageIndex,
    double productPrice,
  ) async {
    final params = {
      'clientId': clientId,
      'storeId': storeId,
      'categoryId': categoryId,
      'storeAreaId': areaId,
      'pageIndex': pageIndex,
      'queryKey': queryKey,
      'pageSize': 10,
      "productPrice": productPrice,
    };
    final response = await _client.post('/api/store/product/query', data: params);
    return StoreProductQuery.fromJson(response.data);
  }

  /// 拼购信息刷新请求对象
  Future<StorePinGou> groupPurchaseRefresh(Floor floor) async {
    final params = {
      "businessType": floor.businessType,
      "groupPurchaseParamId": floor.groupPurchaseParamId,
      "groupPurchaseTeamId": floor.groupPurchaseTeamId,
      "priceAccountType": floor.priceAccountType,
      "productPrice": floor.productPrice,
    };
    final response = await _client.post("/api/grouppurchase/refresh", data: params);
    return StorePinGou.fromJson(response.data);
  }

  /// 商品搜索
  Future<Search> search(String keyword, int page) async {
    var params = {'q': keyword, 'p': page, 'ps': 10};
    var response = await _client.get('/api/search', queryParameters: params);
    return Search.fromJson(response.data);
  }

  /// 店铺搜索
  Future<StoreSearch> storeSearch(String keyword, int page) async {
    var params = {'q': keyword, 'p': page, 'ps': 10};
    var response = await _client.get('/api/storesearch', queryParameters: params);
    return StoreSearch.fromJson(response.data);
  }

  /// 获取店铺商品分类信息
  Future<StoreCategories> storeCategories(
    int storeId,
    int parentCategoryId,
    int layerLevel,
    CancelToken cancelToken,
  ) async {
    var params = <String, dynamic>{};
    params['clientId'] = clientId;
    params['storeId'] = storeId;
    params['parentCategoryId'] = parentCategoryId;
    params['layerLevel'] = layerLevel;
    var response = await _client.post(
      '/api/store/categories/v2',
      data: params,
      cancelToken: cancelToken,
    );
    return StoreCategories.fromJson(response.data);
  }

  /// 店铺新闻公告查询接口
  Future<NewsQuery> newsQuery(Map<String, dynamic> params) async {
    // params['storeId'] = storeId;
    // params['linkType'] = linkType;
    // params['queryKey'] = _queryKey;
    // params['pageIndex'] = 0;
    params['pageSize'] = 10;
    params['clientId'] = clientId;
    var response = await _client.post('/api/news/query', data: params);
    return NewsQuery.fromJson(response.data);
  }

  /// 获取锁粉列表
  Future<UserInvited> userInvited(int currentUserId, int targetUserId, int page) async {
    var params = <String, dynamic>{};
    params['currentUserId'] = currentUserId;
    params['targetUserId'] = targetUserId;
    params['levelOffset'] = 1;
    params['pageIndex'] = page;
    params['pageSize'] = 10;
    var response = await _client.post('/api/user/invited', data: params);
    return UserInvited.fromJson(response.data);
  }

  /// 查询用户续费信息接口
  Future<UserRenewList> userRenewList(int userId, String businessType) async {
    var params = <String, dynamic>{};
    params['u'] = userId;
    params['b'] = businessType;
    var response = await _client.get('/api/user/renew/list', queryParameters: params);
    return UserRenewList.fromJson(response.data);
  }

  /// 店铺申领查询
  Future<StoreApplyQuery> storeApplyQuery(CancelToken cancelToken) async {
    var response = await _client.post('/api/store/apply/query');
    return StoreApplyQuery.fromJson(response.data);
  }

  /// 店铺标准申请接口
  Future<StoreApplyQuery> storeApplyStd(
    Map<String, dynamic> params,
    CancelToken cancelToken,
  ) async {
    // params['id'] = id;
    // params['name'] = name;
    // params['logoFile'] = logoFile;
    // params['idCardFile'] = idCardFile;
    // params['licenseFile'] = licenseFile;

    var logoFile = params['logoFile'] as File;
    var idCardFile = params['idCardFile'] as File;
    var licenseFile = params['licenseFile'] as File;
    if (logoFile != null) {
      params['logoFile'] = await MultipartFile.fromFile(
        logoFile.path,
        filename: 'logoFile.png',
      );
    }
    if (idCardFile != null) {
      params['idCardFile'] = await MultipartFile.fromFile(
        idCardFile.path,
        filename: 'idCardFile.png',
      );
    }
    if (licenseFile != null) {
      params['licenseFile'] = await MultipartFile.fromFile(
        licenseFile.path,
        filename: 'licenseFile.png',
      );
    }
    var response = await _client.post(
      '/api/store/apply/std',
      data: FormData.fromMap(params),
      cancelToken: cancelToken,
    );
    return StoreApplyQuery.fromJson(response.data);
  }

  /// 订单再次支付
  Future<OrderCheckout> orderRepay(String code) async {
    var response = await _client.post('/api/order/repay/$code');
    return OrderCheckout.fromJson(response.data);
  }

  /// 订单确认收货
  Future orderConfirmReceipt(String code) async {
    var response = await _client.post('/api/order/$code/confirm');
    return response.data;
  }

  /// 删除超时订单
  Future orderDelete(String code) async {
    var response = await _client.post('/api/order/$code/delete');
    return response.data;
  }

  /// 获取当前店铺的各类信息统计数量
  Future<StoreTotal> storeTotal(int storeId) async {
    var params = {"sid": storeId};
    var response = await _client.get('/api/store/total', queryParameters: params);
    return StoreTotal.fromJson(response.data);
  }

  /// 通过物流单号和快递公司编码查询快递物流信息，返回的数据第三方数据，只做中转
  Future<Logistics> logistics(String num, String type) async {
    var params = {"num": num, "type": type};
    var response = await _client.get('/api/logistics', queryParameters: params);
    return Logistics.fromJson(jsonDecode(response.data));
  }

  /// 店铺LOGO信息查询接口
  Future<String> storeLogoQuery() async {
    var response = await _client.get('/api/store/logo/query');
    return response.data;
  }

  /// 拼购-当前用户查询拼购窗口信息
  Future<TeamAndPort> groupPurchaseQuery(int modelInAreaId, int pageIndex) async {
    final response = await _client.get(
      "/api/grouppurchase/port/query/$modelInAreaId/10/$pageIndex",
    );
    return TeamAndPort.fromJson(response.data);
  }

  /// 加入某个商品的全网拼购
  Future groupPurchaseJoin(
    int modelInAreaId,
    int addressId,
    String payPassword,
    List<int> selectedPortIds,
  ) async {
    final params = {
      "modelInAreaId": modelInAreaId,
      "addressInfoId": addressId,
      "payPassword": payPassword,
      "selectedPortIds": selectedPortIds,
    };
    final response = await _client.post("/api/grouppurchase/join", data: params);
    return response.data;
  }

  /// 为当前用户开通指定的拼购窗口
  Future groupPurchaseOpen(
    int modelInAreaId,
    String accountType,
    String payPassword,
    int portCount,
  ) async {
    final params = {
      "modelInAreaId": modelInAreaId,
      "accountType": accountType,
      "payPassword": payPassword,
      "portCount": portCount,
    };
    final response = await _client.post("/api/grouppurchase/port/open", data: params);
    return response.data;
  }

  /// 查询拼购历史记录
  Future<List<GroupHistoryRes>> groupPurchaseHistory(
    String yearCondition,
    String statusCondition,
    String userPortMappingId,
    int pageIndex,
  ) async {
    final params = {
      "yearCondition": yearCondition,
      "statusCondition": statusCondition,
      "userPortMappingId": userPortMappingId,
      "pageIndex": pageIndex,
      "pageSize": 10,
    };
    final response = await _client.post("/api/grouppurchase/history", data: params);
    return response.data.map<GroupHistoryRes>((value) => GroupHistoryRes.fromJson(value)).toList();
  }

  /// 修改账户的保护密码
  Future userAccountPasswordChange(
    String accountType,
    String oldPassword,
    String newPassword1,
    String newPassword2,
    bool needPassword,
  ) async {
    final params = {
      "accountType": accountType,
      "oldPassword": oldPassword,
      "newPassword1": newPassword1,
      "newPassword2": newPassword2,
      'needPassword': needPassword,
    };
    final response = await _client.post("/api/useraccount/password/change", data: params);
    return response.data;
  }

  /// 获取当前用户可以兑入的积分账户类型
  Future<List<PointExchangeAccount>> pointExchangeTypeIn(bool displayBalance) async {
    final response = await _client.get("/api/point/exchange/type/in/$displayBalance");
    return response.data
        .map<PointExchangeAccount>((value) => PointExchangeAccount.fromJson(value))
        .toList();
  }

  /// 获取某兑入账户类型对应的可兑出的积分账户类型
  Future<List<PointExchangeAccount>> pointExchangeTypeOut(
    String inAccountType,
    bool displayBalance,
  ) async {
    final response = await _client.get(
      "/api/point/exchange/type/out/$inAccountType/$displayBalance",
    );
    return response.data
        .map<PointExchangeAccount>((value) => PointExchangeAccount.fromJson(value))
        .toList();
  }

  /// 积分兑换
  Future pointExchange(
    String inAccountType,
    String outAccountType,
    String outAmount,
    String payPassword,
    String note,
  ) async {
    final params = {
      "inAccountType": inAccountType,
      "outAccountType": outAccountType,
      "outAmount": outAmount,
      "payPassword": payPassword,
      "note": note,
    };
    final response = await _client.post("/api/point/exchange", data: params);
    return response.data;
  }

  /// 查询积分兑换历史
  Future<List<PointExchangeHistoryRes>> pointExchangeHistory(
    String inAccountType,
    String outAccountType,
    DateTime startTime,
    DateTime endTime,
    int pageIndex,
  ) async {
    final dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
    final params = {
      "inAccountType": inAccountType,
      "outAccountType": outAccountType,
      "startTime": startTime == null ? null : dateFormat.format(startTime),
      "endTime": endTime == null ? null : dateFormat.format(endTime),
      "pageIndex": pageIndex,
      "pageSize": 10,
    };
    final response = await _client.post("/api/point/exchange/history", data: params);
    return response.data
        .map<PointExchangeHistoryRes>((value) => PointExchangeHistoryRes.fromJson(value))
        .toList();
  }

  /// 清除某用户在某个窗口的累计中单次数
  Future groupPurchaseClearHit(int modelInAreaId, int portId) async {
    final response = await _client.get("/api/grouppurchase/clearhit/$modelInAreaId/$portId");
    return response.data;
  }

  /// 获取某个父级分类的子分类列表
  Future<StoreCategories> category(int layerLevel, int parentId, {int storeId}) async {
    final params = {
      "clientId": clientId,
      "layerLevel": layerLevel,
      "parentCategoryId": parentId,
      "storeId": storeId,
    };
    final url = storeId == null ? "/api/categories/v2" : "/api/store/categories/v2";
    final response = await _client.post(url, data: params);
    return StoreCategories.fromJson(response.data);
  }

  /// 拼购历史筛选参数
  Future<List<dynamic>> groupPurchaseHistoryParamYear(String businessType) async {
    final response = await _client.get("/api/grouppurchase/history/param/year/$businessType");
    return response.data;
  }

  /// 拼购历史筛选参数
  Future<Map<String, dynamic>> groupPurchaseHistoryParamStatus(String businessType) async {
    final response = await _client.get("/api/grouppurchase/history/param/status/$businessType");
    return response.data;
  }

  /// 拼购历史筛选参数
  Future<Map<String, dynamic>> groupPurchaseHistoryParamPort(String businessType) async {
    final response = await _client.get("/api/grouppurchase/history/param/port/$businessType");
    return response.data;
  }

  /// 当前用户的账户资金变动统计查询接口
  Future<AccountDetail> userAccountDetailTotal(
    int accountId,
    int pageIndex,
    String selectedTimeQuery,
    String selectedTotalItem,
  ) async {
    final params = {
      'accountId': accountId,
      'pageIndex': pageIndex,
      'pageSize': 10,
      'selectedTimeQuery': selectedTimeQuery,
      'selectedTotalItem': selectedTotalItem,
    };
    final response = await _client.post('/api/useraccount/detail/total', data: params);
    return AccountDetail.fromJson(response.data);
  }
}
